﻿/****************

// You can make the function return it's OWN name.
	tools.getFunctionName(new Error()):String

// return the result to the filetype
// ****** tools.SWF, tools.IMG, tools.HTML
	tools.filetype([path:String]):String

// input "stage"/"this" for the root of SWF;
// ps: it just work on "http://"
	tools.getDomain([stage/this]):String

// return Item in lib, search by Class name; return as ...whatever you want.;
	tools.searchLib( [Object in the lib:String] ):*

// Get the Object's Class
// usage : if (myObj1 is tools.getClass(myObj2))
	tools.getClass( object );
	
// Display the Array, Object's value info.
	tools.varInfo([*], [debug.msg_name:Optional]):String

// Fill Char
// like [11,731,9999] to "00011","00731","09999".
	tools.format([Number], [Output_String_Length:Number], Fill_Char:String="0"):String

// Dec VS HEX
	tools.hex2dec( "0xFFCC33" ):String
	tools.dec2hex( "12345678" ):String

// remove allChild in current DisplayObject
	tools.emptySprite([DisplayObject]):void;
	
// for Array's easy insert / delete
	tools.insertTo([Array], int, "value"):Array;
	tools.deleteAt([Array], _begin:uint, _end:uint):Array;
	
// Copy a new target Object.
	tools.CopyObj(_obj:DisplayObject)

// Check Object's child name exist or not, return true/false
	tools.has(_obj:Object, _name:String)

// Find max/min in Array, when Fail return false;
	tools.min(_array:Array):*;
	tools.max(_array:Array):*;
****************/
package com.cf.core.Utils{
		import flash.display.DisplayObject;
        import flash.display.Sprite;
		import flash.events.Event;
		import flash.events.EventDispatcher;
        import flash.utils.getDefinitionByName;
		import flash.utils.getQualifiedClassName;
		
		import com.cf.core.events.UIEvent;
        public class tools {
				// You can make the function return it's OWN name.
				// Usage :
				// function fn_ABC(){ debug.msg("My name is - "+ tools.getFunctionName(new Error()) );
				//
				// output : My name is - xxxxx::XXX$/fn_ABC
				// 
				public static function getFunctionName(e:Error):String {
					try{
						var stacktrace:String = e.getStackTrace();     // entire stack debug.msg
						var startIndex:int = stacktrace.indexOf("at ");// start of first line
						var endIndex:int = stacktrace.indexOf("()");   // end of function name
						return stacktrace.substring(startIndex + 3, endIndex);
					}catch(ee){}
					return "undefined";
				}//fn
				public static function getClass(obj:Object):Class{
					return Class(getDefinitionByName(getQualifiedClassName(obj)));
				}//fn

				public static const SWF:String = "FiletypeSWF";
				public static const IMG:String = "FiletypeIMG";
				public static const HTML:String = "FiletypeHTML";
				public static function filetype(path:String):String{
					// return the result to the filetype
					var tmp:String="undefined";
					// debug.msg("Trim between '.'&'?' = "+path.substr(path.lastIndexOf(".") + 1, ((path.indexOf("?")>0)?path.substr(path.lastIndexOf(".")+1,path.length-1).indexOf("?"):path.length-1) ).toLowerCase() );
					switch( path.substr(path.lastIndexOf(".") + 1, ((path.indexOf("?")>0)?path.substr(path.lastIndexOf(".")+1,path.length-1).indexOf("?"):path.length-1) ).toLowerCase() ){
						case "swf":
							tmp=SWF;
							break;
						case "jpg": case "jpeg": case "png": case "gif": case "bmp":
							tmp=IMG;
							break;
						case "html": case "htm": case "php": case "asp": case "aspx": case "xml": case "xsl":
							tmp=HTML;
							break;
						default: break;
					}//fn
					// debug.msg("tools.filetype ["+path+"] is "+tmp);
					return tmp;
				}//fn
				
				public static function getDomain(obj:Object):String{
					// input "stage"/"this" for the root of SWF;
					// ps: it just work on "http://"
					var uri:String = obj.loaderInfo.loaderURL;
					uri = uri.substring(uri.indexOf("//")+2, uri.length);
					uri = uri.substring(0, uri.indexOf("/"));
					var urp:String = obj.loaderInfo.loaderURL;
					urp = urp.substring(0, urp.indexOf("//")+2);
					uri = urp + uri;
					return uri;
				}//fn
				
				/* /////////////////////////////////////////////////
				public static function searchLib_v2(_obj:*):*{
					// if the object is string, search lib.
					if(typeof(_obj) is String){return searchLib(_obj)}
					return _obj;
				}//fn */////////////////////////////////////////////
                public static function searchLib(_libname:String):* {
                        // return Item in lib, search by Class name; return as ...whatever you want.;
                        try {
                                var UIClass:Class=getDefinitionByName(_libname) as Class;
                        } catch (e:Error) {
                                debug.msg("searchLib - "+_libname+" can't define, please check the component exist or not.");
                                return false;
                        }//try
                        try {
                                var instance:Object=new UIClass  ;
                        } catch (e:Error) {
                                debug.msg("searchLib - "+_libname+"-"+UIClass+"can't transform to any Object type");
                                return false;
                        }//try
                        return instance;
                }//fn
               
                // For Dev Only. return by plainText :: Analysis Object's construct
                public static function varInfo(obj:*,_Pname:String="obj"):String{
                        var tmp:String="";
                        var prefix:String;
                        for(var prop in obj){
                                prefix = _Pname;
                                prefix+=(prop is Number)?"["+prop+"]":"."+prop;
								if(obj[prop]!=null){
	                                switch(obj[prop].constructor){
                                        default: // just display it
											try{
                                                tmp+=prefix+":Uknow:"+obj[prop].constructor+" = "+obj[prop]+"\n";
											}catch(e){
												tmp+=prefix+":Uknow = undefined\n";
											}
                                        break;
                                        case String: case Number: case Boolean: case Date:
											try{
												tmp+=prefix+":"+obj[prop].constructor+" = "+obj[prop]+"\n";
											}catch(e){
												tmp+=prefix+":ERR = undefined\n";
											}
                                        break;
                                        case Object: case Array:
												tmp+=prefix+"\n"+varInfo(obj[prop],prefix);
                                        break;
    	                            }//case
								}else{
									tmp+=prefix+":null\n";
								}
                        }//for
                        return tmp;
                }//fn
               
                public static function format(inNumber:Number, inFillLength:Number, inFillChar:String="0"):String{
                        var val:String = inNumber.toString();
                        // If inFillLength is defined, add the necessary number of leading characters first.
                        if (inFillLength != 0) {
                                // what char to use?
                                var char:String = inFillChar;
                                // Store the original length before adding spaces.
                                var origLength:Number = val.length;
                                for (var i:int=0; i<inFillLength-origLength; ++i) {
                                        val = char + val;
                                }//for
                        }//if
                        return val;
                }//fn
				
				public static function hex2dec( hex:String ) : String {
					var bytes:Array = [];
					while( hex.length > 2 ) {
						var byte:String = hex.substr( -2 );
						hex = hex.substr(0, hex.length-2 );
						bytes.splice( 0, 0, int("0x"+byte) );
					}//while
					return bytes.join(" ");
				}//fn
				private static function d2h( d:int ) : String {
					var c:Array = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ];
					if( d > 255 ) d = 255;
					var l:int = d / 16;
					var r:int = d % 16;
					return c[l]+c[r];
				}//fn
				public static function dec2hex( dec:String ) : String {
					var hex:String = "0x";
					var bytes:Array = dec.split(" ");
					for( var i:int = 0; i < bytes.length; i++ )
					hex += d2h( int(bytes[i]) );
					return hex;
				}//fn
				// Delete MovieClip/Sprite/DisplayOjbect 's Children
				public static function emptySprite(obj:*):void{
					try{
						for(var i:int=obj.numChildren-1; i>=0; i--) obj.removeChildAt(0);
					}catch(e){}
				}//fn
				
				// for Array's easy insert.
				public static function insertTo(_a:Array, _n:int, _s:*):Array{
					_a.splice(_n, 0, _s);
					return _a;
				}//fn
				// for Array's delete element.
				public static function deleteAt(_arr:Array, _begin:uint=0, _end:uint=1):Array {
					_arr.splice(_begin, _end);
					return _arr;
				}//fn
				
				
				// Copy object
				public static function CopyObj(_obj:DisplayObject):DisplayObject{
					var _objClass:Class = Object(_obj).constructor;
					var _copyObj:DisplayObject = new _objClass();
					return _copyObj;
				}//fn
				
				// have object
				public static function has(_obj:*, _name:String):Boolean {
					var _flag:Boolean = false;
					for (var i in _obj) {
						if (i == _name) {
							_flag = true;
							break;
						}//if
					}//for
					return _flag;
				}//fn
				
				// Find min in Array
				public static function min(_arr:Array):*{
					if ( _arr.length < 1 ) return false;
					var _min:* = _arr[0];
					for (var _i:uint = 0; _i < _arr.length; _i++) {
						if ( _arr[_i] < _min ) _min = _arr[_i];
					}//for
					return _min;
				}//fn
				
				// Fin max in Array
				public static function max(_arr:Array):*{
					if (_arr.length < 1) return false;
					var _max:* = _arr[0];
					for (var _i:uint = 0; _i < _arr.length; _i++) {
						if ( _arr[_i] > _max ) _max = _arr[_i];
					}//for
					return _max;
				}//fn
				
				// ArrayObjectFilter
				// e.g. > var ppl:Array = [{name:"ann",info: { age:19, height:166 }},{name:"bob",info: { age:22, height:159 }},{name:"ken",info: { age:36, height:170 }},{name:"lee",info: { age:5, height:80 }}];
				// as array[0].paths...paths.child to singe array.
				// arrayObjectFilter(ppl,".info.age"):array
				public static function arrayObjectFilter(_array:Array, _paths:String):Array {
					var _result:Array = new Array;
					var _path:Array = _paths.split(".");
					if (_path[0] == "") _path = deleteAt(_path, 0);	// for input error fix [.path1.path2] rewrite [path1.path2]
					for (var _i:uint = 0; _i < _array.length; _i++) {
						var _current:* = _array[_i];
						for (var _k:uint = 0; _k < _path.length; _k++) {
							_current = _current[_path[_k]];
						}//for
						_result.push( _current );
					}//for
					return _result;
				}//fn
        }//class
}//package